﻿using LibNiconico.NiconicoApi.Extentions;
using LibNiconico.NiconicoApi.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LibNiconico.NiconicoApi.Lives.Broadcast
{
    /// <summary>
    /// 主要カテゴリ
    /// </summary>
    public enum PrimaryCategory
    {
        /// <summary>
        /// 選択なし
        /// </summary>
        None,

        /// <summary>
        /// 一般(その他)
        /// </summary>
        General,

        /// <summary>
        /// 政治
        /// </summary>
        Politics,

        /// <summary>
        /// 動物
        /// </summary>
        Animal,

        /// <summary>
        /// 料理
        /// </summary>
        Cooking,

        /// <summary>
        /// 演奏してみた
        /// </summary>
        TriedToPlay,

        /// <summary>
        /// 歌てっみた
        /// </summary>
        TriedToSing,

        /// <summary>
        /// 描いてみた
        /// </summary>
        TriedToDraw,

        /// <summary>
        /// 踊ってみた
        /// </summary>
        TriedDancing,

        /// <summary>
        /// 講座
        /// </summary>
        Course,

        /// <summary>
        /// ゲーム
        /// </summary>
        Game,

        /// <summary>
        /// 動画紹介
        /// </summary>
        VideoIntrodaction,

        /// <summary>
        /// R18
        /// </summary>
        R18,

        
    }

    /// <summary>
    /// カテゴリ拡張
    /// </summary>
    public static class CategoryExtention
    {
        /// <summary>
        /// 名前を取得
        /// </summary>
        /// <param name="primaryCategory"></param>
        /// <returns></returns>
        public static string GetName(this PrimaryCategory primaryCategory)
        {
            switch (primaryCategory)
            {
                case PrimaryCategory.General:
                    return "一般(その他)";

                case PrimaryCategory.Politics:
                    return "政治";

                case PrimaryCategory.Animal:
                    return "動物";

                case PrimaryCategory.Cooking:
                    return "料理";

                case PrimaryCategory.TriedToPlay:
                    return "演奏してみた";

                case PrimaryCategory.TriedToSing:
                    return "歌ってみた";

                case PrimaryCategory.TriedDancing:
                    return "踊ってみた";

                case PrimaryCategory.TriedToDraw:
                    return "描いてみた";

                case PrimaryCategory.Course:
                    return "講座";

                case PrimaryCategory.Game:
                    return "ゲーム";

                case PrimaryCategory.VideoIntrodaction:
                    return "動画紹介";

                case PrimaryCategory.R18:
                    return "R18";

                case PrimaryCategory.None:
                    return "";

                default:
                    throw new ArgumentException();
            }
        }


        /// <summary>
        /// 名前を取得
        /// </summary>
        /// <param name="secondaryCategory"></param>
        /// <returns></returns>
        public static string GetName(this SecondaryCategory secondaryCategory)
        {
            switch (secondaryCategory)
            {
                case SecondaryCategory.None:
                    return "";

                case SecondaryCategory.OutFace:
                    return "顔出し";

                case SecondaryCategory.AssaultWait:
                    return "凸待ち";

                case SecondaryCategory.CruiseWait:
                    return "クルーズ待ち";

                default:
                    throw new ArgumentException();
            }
        }

    }

    /// <summary>
    /// 追加カテゴリ
    /// </summary>
    public enum SecondaryCategory
    {
        /// <summary>
        /// 選択なし
        /// </summary>
        None,

        /// <summary>
        /// 顔出し
        /// </summary>
        OutFace,

        /// <summary>
        /// 凸待ち
        /// </summary>
        AssaultWait,

        /// <summary>
        /// クルーズ待ち
        /// </summary>
        CruiseWait,

        

    }

    /// <summary>
    /// 生放送公開範囲
    /// </summary>
    public enum NicoLivePublicStatus
    {
        /// <summary>
        /// 全員
        /// </summary>
        All,

        /*
        /// <summary>
        /// PCのみ
        /// </summary>
        //PCOnly,
        */

        /// <summary>
        /// コミュニティ限定
        /// </summary>
        CommunityOnly
    }



    /// <summary>
    /// ニコ生放送枠とり問い合わせ情報
    /// </summary>
    public class NicoLiveBroadcastCreateQueryInfo:NicoMultPartPostAble
    {
        /// <summary>
        /// タイトル
        /// </summary>
        public string Title { get; set; }

        /// <summary>
        /// 詳細
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// コミュニティ情報
        /// </summary>
        public NicoLiveBroadcastableCommunityInfo DefaultCommunity { get; set; }

        /// <summary>
        /// タグ
        /// </summary>
        public NicoLiveTagList Tags { get; private set; }

        /// <summary>
        /// 公開範囲
        /// </summary>
        public NicoLivePublicStatus PublicStatus { get; set; }

        /// <summary>
        /// 主要カテゴリ
        /// </summary>
        public PrimaryCategory PrimaryCategory { get; set; }

        /// <summary>
        /// 追加カテゴリ
        /// </summary>
        public HashSet<SecondaryCategory> SecondaryCategorys { get; private set; }

        /// <summary>
        /// タイムシフト有効/無効
        /// </summary>
        public bool TimeShiftEnabled { get; set; }


        /// <summary>
        /// 広告設定
        /// </summary>
        public bool AdEnable { get; set; }


        /// <summary>
        /// ツイッター無効設定
        /// </summary>
        public bool TwitterDisabled { get; set; }



        /// <summary>
        /// ツイッターハッシュタグ(プライベート)
        /// </summary>
        private string twtterTag;

        /// <summary>
        /// ツイッターハッシュタグ
        /// </summary>
        public string TwitterTag
        {
            get
            {
                return this.twtterTag;
            }

            set
            {


                //nullか文字数が0だった場合ArgumentNullExceptionを投げる
                if (value == null || value.Length <= 0 ) throw new ArgumentNullException();


                //#が2文字以上だったらArgumentExceptionを投げる
                var sharpCharctors = from charctor in value.ToCharArray()
                                     where charctor == '#'
                                     select charctor;
                var sharpCount = sharpCharctors.Count();
                if (sharpCount >= 2) throw new ArgumentException();


                //先頭に#がある場合はそのまま代入、ない場合は#をつけて代入
                if (sharpCount == 1)
                {

                    if (value[0] == '#')
                    {
                        this.twtterTag = value;
                    }
                    else
                    {
                        throw new ArgumentException();
                    }
                    
                    
                }
                else
                {
                    this.twtterTag = "#" + value;
                }

            }

        }


        private const string public_status_name = "public_status";

        private const string tags_name = "tags[]";

        private const string livetags = "livetags";

        private const string taglock = "taglock";

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public NicoLiveBroadcastCreateQueryInfo()
        {
            this.DefaultCommunity = null;
            this.Description = "";
            this.PublicStatus = NicoLivePublicStatus.All;
            this.PrimaryCategory = Broadcast.PrimaryCategory.None;
            this.SecondaryCategorys = new HashSet<SecondaryCategory>();
            this.Tags = new NicoLiveTagList();
            this.TimeShiftEnabled = false;
            this.AdEnable = true;
            this.TwitterDisabled = true;
            this.Title = "";
            this.twtterTag = "";
            
        }

        internal override byte[] AsPostData()
        {

            if (this.DefaultCommunity == null) throw new ArgumentNullException("DefaultCommunityが設定されていません");


            var query = new MultiPartFormData();

            query.Add("is_wait", "");

            query.Add("usecoupon", "");

            query.Add("title", this.Title);
            query.Add("description", this.Description);

            query.Add("default_community", this.DefaultCommunity.CommunityId);


            query.Add(tags_name, this.PrimaryCategory.GetName());

            foreach (var secondaryCategory in this.SecondaryCategorys)
            {

                query.Add(tags_name, secondaryCategory.GetName());
            }

            
            int tagNumber;
            for (var tagIndex = 0; tagIndex < this.Tags.Count; tagIndex++)
            {
                var tag = this.Tags[tagIndex];
                tagNumber = tagIndex + 1;
                query.Add(livetags + tagNumber, tag.TagName);

                if (tag.TagLock)
                {
                    query.Add(taglock + tagNumber, "ロックする");
                }


            }



            query.Add("all_remain_point", "0");

            query.Add("reserved", "");

            query.Add("extension", "");

            query.Add("charge_type", "is_reserved");

            switch (this.PublicStatus)
            {


                case NicoLivePublicStatus.CommunityOnly:
                    query.Add(public_status_name,"2");
                    break;


            }

            query.Add("ad_enable", this.AdEnable ? "1" : "0");


            query.Add("timeshift_enabled", this.TimeShiftEnabled ? "1" : "0");

            query.Add("twitter_disabled", this.TwitterDisabled ? "1" : "0");


            query.Add("input_twitter_tag", this.TwitterTag);

            query.Add("twitter_tag", this.TwitterTag);


            query.Add("submit_ok", "確認する");


            

            

            return Encoding.UTF8.GetBytes(query.ToString());
        }

        internal override string AsPath()
        {
            return "editstream";
        }

        internal override string AsQuery()
        {
            return "";
        }
    }
}
